package com.zego.wawaji.ui.play;

import android.content.Context;
import android.os.CountDownTimer;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.noble.library.observer.MsgMgr;
import com.noble.library.observer.PObserver;
import com.zego.wawaji.R;
import com.zego.wawaji.base.module.ModuleMgr;
import com.zego.wawaji.base.observer.MsgType;
import com.zego.wawaji.base.toast.PToast;
import com.zego.wawaji.ui.base.BasePanel;
import com.zego.wawaji.ui.base.CustomFrameLayout;
import com.zego.wawaji.ui.bean.user.UserDetail;
import com.zego.wawaji.ui.bean.wawa.WawaJi;
import com.zego.wawaji.ui.dialog.LoadingDialog;
import com.zego.wawaji.ui.dialog.PickerDialogUtil;
import com.zego.wawaji.wawaji_client.cmd.CommandUtil;
import com.zego.wawaji.wawaji_client.play.BoardState;
import com.zego.wawaji.wawaji_client.play.PlayStatus;
import com.zego.wawaji.wawaji_client.util.OnSoundClickListener;
import com.zego.wawaji.wawaji_client.util.PreferenceUtil;
import com.zego.zegoliveroom.ZegoLiveRoom;
import com.zego.zegoliveroom.constants.ZegoConstants;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 操作panel
 * Created by Su on 2017/11/25.
 */
public class PlayHandle extends BasePanel implements PObserver {
    private WawaJi mRoom;                         // 房间信息
    private int mCurrentQueueCount = 0;         // 当前预约人数

    private ImageButton mIBtnApply;     // 预约
    private TextView queueNum;          // 排队人数
    private boolean isCanApply = false;  // 先屏蔽预约按钮，等待房间初始化成功

    // 操控
    private CustomFrameLayout handleLayout;
    private ImageButton mIBtnBackward;
    private ImageButton mIBtnLeft;
    private ImageButton mIBtnForward;
    private ImageButton mIBtnRight;
    private ImageButton mIBtnGO;
    private TextView mTvBoardingCountDown; // 计时
    private CountDownTimer mCountDownTimerBoarding;     // 游戏中倒计时

    // 等待游戏结果计时
    private CountDownTimer mGameResultTimer;

    private TextView playPrice;             // 娃娃机游戏价格
    private int priceNum;                   // 游戏需要娃娃币数量
    private TextView coinRemain;            // 用户剩余娃娃币

    private UserDetail userDetail;
    private ZegoLiveRoom mZegoLiveRoom;
    private List<String> queueHead = new ArrayList<>();     // 预约队列中用户头像

    public PlayHandle(Context context, WawaJi mRoom, ZegoLiveRoom mZegoLiveRoom) {
        super(context);
        setContentView(R.layout.play_handle_panel);
        this.mZegoLiveRoom = mZegoLiveRoom;
        this.mRoom = mRoom;
        initView();
//        initLongPush();
    }

    private void initView() {
        MsgMgr.getInstance().attach(this);
        userDetail = ModuleMgr.getCenterMgr().getMyInfo();
        mTvBoardingCountDown = (TextView) findViewById(R.id.tv_boarding_countdown);
        coinRemain = (TextView) findViewById(R.id.coin_remain);
        findViewById(R.id.btn_recharge).setOnClickListener(listener);

        priceNum = mRoom.getPrice();
        playPrice = (TextView) findViewById(R.id.play_price);
        playPrice.setText(priceNum + "币/次");
        coinRemain.setText(String.valueOf(userDetail.getTotalWwCoin()) + "币");

        subscribe();
        handleDevice();
        setControlPannel(false);
    }

    public void refreshCoin() {
        userDetail = ModuleMgr.getCenterMgr().getMyInfo();
        coinRemain.setText(String.valueOf(userDetail.getTotalWwCoin()) + "币");
    }

    /**
     * 更新用户剩余娃娃币
     */
    private void refreshCoinRemain() {
        userDetail.setTotalWwCoin(userDetail.getTotalWwCoin() - priceNum);
        coinRemain.setText(String.valueOf(userDetail.getTotalWwCoin()) + "币");
    }

    /**
     * 初始化预约状态
     */
    private void subscribe() {
        mIBtnApply = (ImageButton) findViewById(R.id.ibtn_apply);
        queueNum = (TextView) findViewById(R.id.tv_queue_num);
        mIBtnApply.setBackgroundResource(R.drawable.btn_begin_game);
        queueNum.setVisibility(View.GONE);
        mIBtnApply.setOnClickListener(listener);
    }

    /**
     * 操作机器
     */
    private void handleDevice() {
        handleLayout = (CustomFrameLayout) findViewById(R.id.handle_layout);

        // 娃娃机操作
        mIBtnLeft = (ImageButton) findViewById(R.id.ibtn_left);
        mIBtnBackward = (ImageButton) findViewById(R.id.ibtn_backward);
        mIBtnForward = (ImageButton) findViewById(R.id.ibtn_forward);
        mIBtnRight = (ImageButton) findViewById(R.id.ibtn_right);
        mIBtnGO = (ImageButton) findViewById(R.id.ibtn_go);

        mIBtnLeft.setOnClickListener(listener);
        mIBtnBackward.setOnClickListener(listener);
        mIBtnForward.setOnClickListener(listener);
        mIBtnRight.setOnClickListener(listener);
        mIBtnGO.setOnClickListener(listener);
    }

    private void showApplyPanel () {
        if (handleLayout != null)
            handleLayout.show(R.id.apply_panel);
    }

    private void showHandlePanel() {
        if (handleLayout != null)
            handleLayout.show(R.id.rlyt_control_pannel);
    }

    private OnSoundClickListener listener = new OnSoundClickListener() {
        @Override
        public void onSoundClick(View v) {
            switch (v.getId()) {
                case R.id.ibtn_apply:
                    if (!isCanApply) {  // SDK未初始化成功
                        PToast.showShort("正在初始化房间，请稍侯...");
                        return;
                    }
                    if (PlayStatus.getCurrentBoardSate() == BoardState.Ended) {
                        LoadingDialog.show(getActivity(), "正在申请预约");
                        // 通知服务端预约申请
                        ModuleMgr.getWawaMgr().reqGameApply(mRoom.getId(), mRoom.getWwTypeId(), response -> {
                            if (!response.isOk()) {
                                LoadingDialog.closeLoadingDialog(200);
                                reinitGame();
                                return;
                            }
                            CommandUtil.getInstance().apply(() -> sendCMDFail("Apply"));
                        });
                    } else if (PlayStatus.getCurrentBoardSate() == BoardState.WaitingBoard) { // 预约状态，取消预约
                        LoadingDialog.show(getActivity(), "正在取消预约");
                        // 即使未取消成功，下次在预约同一房间娃娃机的话，服务端会检测该用户是否在预约队列中, 只发不接收结果
                        CommandUtil.getInstance().cancelApply();
                        LoadingDialog.closeLoadingDialog(500, () -> reinitGame());
                    }
                    break;
                case R.id.ibtn_left:
                    if (PlayHelper.mSwitchCameraTimes % 2 == 1) {
                        CommandUtil.getInstance().moveForward();
                    } else {
                        CommandUtil.getInstance().moveLeft();
                    }
                    break;

                case R.id.ibtn_backward:
                    if (PlayHelper.mSwitchCameraTimes % 2 == 1) {
                        CommandUtil.getInstance().moveLeft();
                    } else {
                        CommandUtil.getInstance().moveBackward();
                    }
                    break;

                case R.id.ibtn_forward:
                    if (PlayHelper.mSwitchCameraTimes % 2 == 1) {
                        CommandUtil.getInstance().moveRight();
                    } else {
                        CommandUtil.getInstance().moveForward();
                    }
                    break;

                case R.id.ibtn_right:
                    if (PlayHelper.mSwitchCameraTimes % 2 == 1) {
                        CommandUtil.getInstance().moveBackward();
                    } else {
                        CommandUtil.getInstance().moveRight();
                    }
                    break;

                case R.id.ibtn_go:
                    if (PlayStatus.getCurrentBoardSate() == BoardState.Boarding) {
                        mCountDownTimerBoarding.cancel();
                        pauseControlPannel();
                        CommandUtil.getInstance().grub(true, null);
                        startWaitGameResultTimer();   // 开启等待结果计时
                    }
                    break;
                case R.id.btn_recharge:  // 跳充值
                    PickerDialogUtil.showPayDialog((FragmentActivity) getActivity());
                    break;
            }
        }
    };

    public void handleConfirmBoardReply(Map<String, Object> data) {
        if (data == null) {
            CommandUtil.getInstance().printLog("[handleConfirmBoardReply], data is null");
            return;
        }
        if (PlayStatus.getCurrentBoardSate() != BoardState.ConfirmBoard) {
            CommandUtil.getInstance().printLog("[handleConfirmBoardReply], state mismatch");
            return;
        }

        if (CommandUtil.getInstance().isConfirmBoard()) {
            // 推流
            mZegoLiveRoom.enableCamera(false);
            mZegoLiveRoom.enableMic(false);
            mZegoLiveRoom.enableDTX(true);
            mZegoLiveRoom.setAudioBitrate(8 * 1000);
            mZegoLiveRoom.startPublishing(mRoom.getImei(), "title_" + mRoom.getImei(), ZegoConstants.PublishFlag.JoinPublish);

            startGame();
            mCountDownTimerBoarding = new CountDownTimer(30000, 500) {
                @Override
                public void onTick(long millisUntilFinished) {
                    if (PlayStatus.getCurrentBoardSate() == BoardState.Boarding) {
                        mTvBoardingCountDown.setVisibility(View.VISIBLE);
                        mTvBoardingCountDown.setText(((millisUntilFinished / 1000) + 1) + "s");
                    }
                }

                @Override
                public void onFinish() {
                    if (PlayStatus.getCurrentBoardSate() == BoardState.Boarding) {
                        pauseControlPannel();  // 游戏中，游戏时间结束后，屏蔽按键点击
                        CommandUtil.getInstance().grub(true, null);
                        startWaitGameResultTimer();
                    }
                }
            }.start();
        }
    }

    private void startGame() {
        PlayStatus.setCurrentBoardSate(BoardState.Boarding);
        setControlPannel(true);
        // 通知服务端开始游戏
        ModuleMgr.getWawaMgr().reqGameAdd(mRoom.getId(), mRoom.getWwTypeId(), null);
    }

    private void reinitGame() {
        PlayStatus.setCurrentBoardSate(BoardState.Ended);
        setControlPannel(false);
        String msg = getActivity().getString(R.string.current_queue_count, mCurrentQueueCount + "");
        if (mCurrentQueueCount == 0) {
            mIBtnApply.setBackgroundResource(R.drawable.btn_begin_game);
            queueNum.setVisibility(View.GONE);
        } else {
            mIBtnApply.setBackgroundResource(R.drawable.btn_begin_queue);
            queueNum.setVisibility(View.VISIBLE);
            queueNum.setText(msg);
        }
        MsgMgr.getInstance().sendMsg(MsgType.MT_Room_Status, mCurrentQueueCount);
        showApplyPanel();
    }

    /**
     * 屏蔽操作键点击事件
     */
    private void pauseControlPannel() {
        mIBtnLeft.setEnabled(false);
        mIBtnForward.setEnabled(false);
        mIBtnRight.setEnabled(false);
        mIBtnBackward.setEnabled(false);
        mIBtnGO.setEnabled(false);
        mTvBoardingCountDown.setText("");
    }

    private void setControlPannel(boolean enable) {
        if (enable) {
            showHandlePanel();
            queueNum.setVisibility(View.GONE);
        } else {
           showApplyPanel();
        }
        MsgMgr.getInstance().sendMsg(MsgType.MT_Playing_Status, enable);

        mIBtnLeft.setEnabled(enable);
        mIBtnForward.setEnabled(enable);
        mIBtnRight.setEnabled(enable);
        mIBtnBackward.setEnabled(enable);
        mIBtnGO.setEnabled(enable);
        mTvBoardingCountDown.setText("");
    }

    /**
     * "预约上机"结果.
     */
    public void handleApplyResult(Map<String, Object> data) {
        LoadingDialog.closeLoadingDialog(200);
        if (data == null) return;

        // 处于正在预约状态，收到指令消息不做处理
        if (PlayStatus.getCurrentBoardSate() != BoardState.Applying) {
            return;
        }

        // 校验seq, 不匹配不处理
        int rspSeq = ((Double) data.get("seq")).intValue();
        if (CommandUtil.getInstance().getCurrentSeq() != rspSeq) {
            return;
        }

        int result = ((Double) data.get("result")).intValue();
        if (result == 0) {
            PlayStatus.setCurrentBoardSate(BoardState.WaitingBoard);
            String msg = getActivity().getString(R.string.apply_success, ((Double) data.get("index")).intValue() + "");
            mIBtnApply.setBackgroundResource(R.drawable.btn_cancel_wait);
            queueNum.setVisibility(View.VISIBLE);
            queueNum.setText(msg);
        } else {
            Toast.makeText(getActivity(), getActivity().getString(R.string.apply_faile), Toast.LENGTH_SHORT).show();
            reinitGame();
        }
    }

    public void sendCMDFail(String cmd) {
        LoadingDialog.closeLoadingDialog();
        Toast.makeText(getActivity(), "网络连接失败", Toast.LENGTH_SHORT).show();
        reinitGame();
    }

    /**
     * 刷新预约队列人数
     */
    public void refreshQueueNum(int count) {
        this.mCurrentQueueCount = count;
        String msg = getActivity().getString(R.string.current_queue_count, mCurrentQueueCount + "");
        if (mCurrentQueueCount == 0) {
            mIBtnApply.setBackgroundResource(R.drawable.btn_begin_game);
            queueNum.setVisibility(View.GONE);
        } else {
            mIBtnApply.setBackgroundResource(R.drawable.btn_begin_queue);
            queueNum.setVisibility(View.VISIBLE);
            queueNum.setText(msg);
        }
        MsgMgr.getInstance().sendMsg(MsgType.MT_Room_Status, mCurrentQueueCount);
    }

    /**
     * 解析CMD中预约人数
     */
    public void parseQueueNum(ArrayList queueList) {
        if (queueList == null) return;
        mCurrentQueueCount = queueList.size();
        refreshQueueNum(mCurrentQueueCount);
        if (queueHead == null) queueHead = new ArrayList<>();

        // 解析预约用户前三位头像地址
        queueHead.clear();
        if (mCurrentQueueCount > 0) {
            int size = mCurrentQueueCount >= 3 ? 3 : mCurrentQueueCount;
            for (int i = 0; i < size; i++) {
                queueHead.add((String) ((Map<String, Object>) queueList.get(i)).get("avatar"));
            }
            MsgMgr.getInstance().sendMsg(MsgType.MT_Queue_Head, queueHead);
        }

        if (PlayStatus.getCurrentBoardSate() == BoardState.Ended) {
            String msg = getContext().getString(R.string.current_queue_count, mCurrentQueueCount + "");
            if (mCurrentQueueCount == 0) {
                mIBtnApply.setBackgroundResource(R.drawable.btn_begin_game);
                queueNum.setVisibility(View.GONE);
            } else {
                mIBtnApply.setBackgroundResource(R.drawable.btn_begin_queue);
                queueNum.setVisibility(View.VISIBLE);
                queueNum.setText(msg);
            }
        } else if (PlayStatus.getCurrentBoardSate() == BoardState.WaitingBoard) {
            for (int i = 0, size = queueList.size(); i < size; i++) {
                if (PreferenceUtil.getInstance().getUserID().equals(((Map<String, Object>) queueList.get(i)).get("id"))) {
                    String msg = getContext().getString(R.string.apply_success, i + "");
                    mIBtnApply.setBackgroundResource(R.drawable.btn_cancel_wait);
                    queueNum.setVisibility(View.VISIBLE);
                    queueNum.setText(msg);
                    break;
                }
            }
        }
    }

    @Override
    public void onMessage(String key, Object value) {
        switch (key) {
            case MsgType.MT_Re_Init_Game:           // 重置游戏状态
                reinitGame();
                break;

            case MsgType.MT_Confirm_Board:  // 用户确认上机
                refreshCoinRemain();
                break;

            case MsgType.MT_Init_Suc:  // SDK初始化成功消息
                isCanApply = (boolean) value;
                break;

            case MsgType.MT_MyInfo_Change:
                refreshCoin();
                PickerDialogUtil.closePayDialog();
                break;
        }
    }

    public void doLogout() {
        isCanApply = false;
        MsgMgr.getInstance().detach(this);
        if (mCountDownTimerBoarding != null) {
            mCountDownTimerBoarding.cancel();
        }

        if (mGameResultTimer != null) {
            mGameResultTimer.cancel();
        }
    }

    // =========================================== 下抓后等待游戏结果 ================================
    private void startWaitGameResultTimer() {
        mGameResultTimer = new CountDownTimer(15000, 500) {
            @Override
            public void onTick(long millisUntilFinished) {
            }

            @Override
            public void onFinish() { // 计时结束未收到游戏结果，重置游戏状态
                ModuleMgr.getWawaMgr().reqGetGameResult(response -> {
                    if (response.isOk()) {
                        JSONObject jsonObject = response.getResponseObject();
                        int result = jsonObject.optInt("Status");
                        PlayHelper.handleResult(result, -1, null);
                    } else {
                        PToast.showShort("获取游戏结果失败");
                        CommandUtil.getInstance().confirmBoard(PlayHelper.rspSeq, "", 0, null);
                        reinitGame();
                    }
                });
            }
        }.start();
    }

    public void stopWaitGameResultTimer() {
        if (mGameResultTimer != null) {
            mGameResultTimer.cancel();
        }
    }
}
